home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / progtool / c / egem_210 / egem / source / tool.c < prev    next >
C/C++ Source or Header  |  1995-11-25  |  30KB  |  1,452 lines

  1.  
  2. #include "proto.h"
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. static int clipping_area[4];
  7. static int handler_events;
  8. static int (*event_init)(XEVENT *,int),(*event_handler)(XEVENT *);
  9.  
  10. char UpperChar(char ch)
  11. {
  12.     if (ch>='a')
  13.     {
  14.         if (ch>'z')
  15.         {
  16.             if (ch=='ä')
  17.                 return ('Ä');
  18.             else if (ch=='ö')
  19.                 return ('Ö');
  20.             else if (ch=='ü')
  21.                 return ('Ü');
  22.         }
  23.         else
  24.             return (ch-32);
  25.     }
  26.  
  27.     return (ch);
  28. }
  29.  
  30. char LowerChar(char ch)
  31. {
  32.     if (ch>='A')
  33.     {
  34.         if (ch>'Z')
  35.         {
  36.             if (ch=='Ä')
  37.                 return ('ä');
  38.             else if (ch=='Ö')
  39.                 return ('ö');
  40.             else if (ch=='Ü')
  41.                 return ('ü');
  42.         }
  43.         else
  44.             return (ch+32);
  45.     }
  46.  
  47.     return (ch);
  48. }
  49.  
  50. static int mouse_off;
  51.  
  52. void MouseOn(void)
  53. {
  54.     mouse_off--;
  55.     if (mouse_off==0)
  56.         graf_mouse(M_ON,NULL);
  57. }
  58.  
  59. void MouseOff(void)
  60. {
  61.     if (mouse_off==0)
  62.         graf_mouse(M_OFF,NULL);
  63.     mouse_off++;
  64. }
  65.  
  66. static int _mode,_lwidth,_lcolor,_fcolor,_finter,_fstyle,_tfont,_theight,_tcolor;
  67.  
  68. void vs_attr(void)
  69. {
  70.     _mode = _lwidth = _lcolor = _fcolor = _finter = _fstyle = _tfont = _theight = _tcolor = -1;
  71. }
  72.  
  73. void _vdi_attr(int mode,int wid,int col)
  74. {
  75.     v_set_mode(mode);
  76.     v_set_line(col,wid);
  77. }
  78.  
  79. void v_set_text(int font,int height,int color,int *out)
  80. {
  81.     if (font!=_tfont)
  82.         vst_font(x_handle,_tfont=font);
  83.  
  84.     if (out!=NULL || height!=_theight)
  85.     {
  86.         int dummy[4];
  87.  
  88.         if (out==NULL)
  89.             out = dummy;
  90.  
  91.         if (height>0)
  92.             vst_height(x_handle,height,&out[0],&out[1],&out[2],&out[3]);
  93.         else
  94.             vst_point(x_handle,-height,&out[0],&out[1],&out[2],&out[3]);
  95.         _theight = height;
  96.     }
  97.  
  98.     if (color!=_tcolor)
  99.         vst_color(x_handle,_tcolor = color);
  100. }
  101.  
  102. void v_set_mode(int mode)
  103. {
  104.     if (mode>=0 && mode!=_mode)
  105.         vswr_mode(x_handle,_mode=mode);
  106. }
  107.  
  108. void v_set_line(int color,int width)
  109. {
  110.     if (width>=0 && width!=_lwidth)
  111.         vsl_width(x_handle,_lwidth=width);
  112.  
  113.     if (color>=0 && color!=_lcolor)
  114.         vsl_color(x_handle,_lcolor=color);
  115. }
  116.  
  117. void v_set_fill(int color,int inter,int style)
  118. {
  119.     if (color>=0 && color!=_fcolor)
  120.         vsf_color(x_handle,_fcolor=color);
  121.  
  122.     if (inter>=0 && inter!=_finter)
  123.         vsf_interior(x_handle,_finter=inter);
  124.  
  125.     if (style>=0 && style!=_fstyle)
  126.         vsf_style(x_handle,_fstyle=style);
  127. }
  128.  
  129. void vsf_aespattern(int handle, int obx, int oby, int patternindex)
  130. {
  131.     static long aespatterns[] = {
  132.         0x00000000L, 0x00440011L, 0x00550055L, 0x88552288L,
  133.         0x55AA55AAL, 0xAADDAA77L, 0x55FF55FFL, 0xFFFFFFFFL };
  134.  
  135.     unsigned long pat;
  136.     reg int i,j,pattern[16];
  137.     reg char *patptr, *p;
  138.  
  139.     pat = aespatterns[patternindex];
  140.  
  141.     obx &= 3;
  142.     pat >>= obx;
  143.     pat &= 0x0F0F0F0FL;
  144.     pat |= (pat<<4);
  145.  
  146.     oby &= 3;
  147.     pat = (pat<<((4-oby)<<3))|(pat>>(oby<<3));
  148.  
  149.     patptr = (char *) pattern;
  150.     for (i=4;--i>=0;)
  151.     {
  152.         p = (char *) &pat;
  153.         for (j=4;--j>=0;)
  154.         {
  155.             *patptr++ = *p;
  156.             *patptr++ = *p++;
  157.         }
  158.     }
  159.  
  160.     vsf_interior(handle, 4);
  161.     vsf_udpat(handle, pattern, 1);
  162. }
  163.  
  164. void v_aespattern(int ob_x, int ob_y, int pattern)
  165. {
  166.     vsf_aespattern(x_handle, ob_x, ob_y, pattern);
  167.     _finter = 4;
  168. }
  169.  
  170. void _line(int x1,int y1,int x2,int y2)
  171. {
  172.     reg int pxy[4];
  173.     
  174.     pxy[0] = x1;
  175.     pxy[1] = y1;
  176.     pxy[2] = x2;
  177.     pxy[3] = y2;
  178.     v_pline(x_handle,2,pxy);
  179. }
  180.  
  181. void _bar(int x,int y,int w,int h,int interior,int style,int color)
  182. {
  183.     reg int pxy[4];
  184.  
  185.     v_set_fill(color,interior,style);
  186.  
  187.     pxy[0] = x;
  188.     pxy[1] = y;
  189.     pxy[2] = x + w;
  190.     pxy[3] = y + h;
  191.     v_bar(x_handle,pxy);
  192. }
  193.  
  194. void _rectangle(int sx,int sy,int dx,int dy)
  195. {
  196.     reg int pxy[10];
  197.  
  198.     pxy[0] = pxy[6] = pxy[8] = sx;
  199.     pxy[1] = pxy[3] = pxy[9] = sy;
  200.     pxy[2] = pxy[4] = dx;
  201.     pxy[5] = pxy[7] = dy;
  202.     v_pline(x_handle,5,pxy);
  203. }
  204.  
  205. void _beg_ctrl()
  206. {
  207.     wind_update(BEG_UPDATE);
  208.     wind_update(BEG_MCTRL);
  209. }
  210.  
  211. void _end_ctrl()
  212. {
  213.     wind_update(END_MCTRL);
  214.     wind_update(END_UPDATE);
  215. }
  216.  
  217. int _mouse_but(void)
  218. {
  219.     int but,dummy;
  220.  
  221.     if (_back_win && !_bevent)
  222.         vq_mouse(x_handle,&but,&dummy,&dummy);
  223.     else
  224.         graf_mkstate(&dummy,&dummy,&but,&dummy);
  225.  
  226.     return(but);
  227. }
  228.  
  229. void _mouse_pos(reg int *x,reg int *y)
  230. {
  231.     int dummy;
  232.     graf_mkstate(x,y,&dummy,&dummy);
  233. }
  234.  
  235. void _no_click()
  236. {
  237.     XEVENT event;
  238.  
  239.     memset(&event,0,sizeof(XEVENT));
  240.     event.ev_mflags = MU_BUTTON1;
  241.     event.ev_mb1mask = 3;
  242.     event.ev_mb1clicks = 1;
  243.  
  244.     _no_button++;
  245.     Event_Multi(&event);
  246.     _no_button--;
  247. }
  248.  
  249. /*************************/
  250.  
  251. int min(int v_1,int v_2)
  252. {
  253.     if (v_1<v_2)
  254.         return(v_1);
  255.     else
  256.         return(v_2);
  257. }
  258.  
  259. int max(int v_1,int v_2)
  260. {
  261.     if (v_1>v_2)
  262.         return(v_1);
  263.     else
  264.         return(v_2);
  265. }
  266.  
  267. void Min(int *var,int val)
  268. {
  269.     if (*var>val)
  270.         *var = val;
  271. }
  272.  
  273. void Max(int *var,int val)
  274. {
  275.     if (*var<val)
  276.         *var = val;
  277. }
  278.  
  279. int scan_2_ascii(int scan,int state)
  280. {
  281.     reg int sc = (int) (((unsigned) scan)>>8);
  282.  
  283.     if (state && sc)
  284.     {
  285.         long old_stack;
  286.         reg KEYTAB *keytab = Keytbl((void *) -1l,(void *) -1l,(void *) -1l);
  287.  
  288.         if (sc>=120 && sc<=131)
  289.             sc -= 118;
  290.  
  291.         if (mint)
  292.             old_stack = (long) Super(NULL);
  293.  
  294.         if (state & 3)
  295.             scan = (int) *(keytab->shift+sc);
  296.         else
  297.             scan = (int) *(keytab->unshift+sc);
  298.  
  299.         if (mint)
  300.             Super((void *) old_stack);
  301.     }
  302.  
  303.     return (UpperChar(scan));
  304. }
  305.  
  306. void mfdb(MFDB *fm,int *adr,int w,int h,int st,int pl)
  307. {
  308.     fm->fd_addr        = adr;
  309.     fm->fd_w        = (w+15) & 0xfff0;
  310.     fm->fd_h        = h;
  311.     fm->fd_wdwidth    = fm->fd_w>>4;
  312.     fm->fd_stand    = st;
  313.     fm->fd_nplanes    = pl;
  314. }
  315.  
  316. long mfdb_size(MFDB *fm)
  317. {
  318.     return ((long) (fm->fd_wdwidth<<1) * (long) fm->fd_h * (long) fm->fd_nplanes);
  319. }
  320.  
  321. int _call_event_handler(int msg,XEVENT *event,int sendkey)
  322. {
  323.     reg XAcc *xacc;
  324.     reg int used,mbuf[8];
  325.  
  326.     if (event_handler!=NULL && (handler_events & msg))
  327.     {
  328.         reg int old = event->ev_mwich;
  329.  
  330.         event->ev_mwich = msg;
  331.         used = event_handler(event);
  332.         event->ev_mwich = old;
  333.     }
  334.     else
  335.         used = 0;
  336.  
  337.     if ((msg & MU_KEYBD) && sendkey && _dia_len==0 && _popup==0 && (used & MU_KEYBD)==0)
  338.     {
  339.         mbuf[3] = event->ev_mmokstate;
  340.         mbuf[4] = event->ev_mkreturn;
  341.  
  342.         if (AvServer>=0)
  343.             AvSendMsg(AvServer,AV_SENDKEY,mbuf);
  344.         else if (!multi && (xacc=find_id(0))!=NULL)
  345.         {
  346.             if (xacc->flag & AV)
  347.                 AvSendMsg(0,AV_SENDKEY,mbuf);
  348.             else
  349.                 XAccSendKey(0, event->ev_mkreturn, event->ev_mmokstate);
  350.         }
  351.     }
  352.  
  353.     return (used);
  354. }
  355.  
  356. void Event_Handler(int (*init)(XEVENT *,int),int (*handler)(XEVENT *))
  357. {
  358.     if (init!=NULL || handler==NULL)
  359.         event_init = init;
  360.  
  361.     if (handler!=NULL || init==NULL)
  362.         event_handler = handler;
  363.  
  364.     if (event_handler==NULL)
  365.         event_init = NULL;
  366. }
  367.  
  368. typedef struct
  369. {
  370.     long    type;
  371.     long    what;
  372. } APPLRECORD;
  373.  
  374. static APPLRECORD record[] = {{1l,0x10000l}, {0l,10l}, {1l,0x100001l}};
  375.  
  376. void Event_Timer(int locount,int hicount)
  377. {
  378.     XEVENT event;
  379.  
  380.     memset(&event,0,sizeof(XEVENT));
  381.     event.ev_mflags = MU_TIMER|MU_MESAG|MU_GET_MESSAG;
  382.     event.ev_mtlocount = locount;
  383.     event.ev_mthicount = hicount;
  384.  
  385.     while (Event_Multi(&event) & MU_MESAG);
  386. }
  387.  
  388. static void iconify(WIN *window,int all)
  389. {
  390.     reg int i,top = _get_top();
  391.  
  392.     if (all)
  393.     {
  394.         i = MAX_WINDOWS;
  395.         window = _windows;
  396.     }
  397.     else
  398.         i = 1;
  399.  
  400.     for (;--i>=0;)
  401.     {
  402.         if (window->handle>0)
  403.         {
  404.             if (top==window->handle)
  405.             {
  406.                  if (_icfs_iconify(window,TRUE,FAIL)==FALSE)
  407.                     break;
  408.                 top = window->handle;
  409.             }
  410.             else if (_icfs_iconify(window,TRUE,FAIL)==FALSE)
  411.                 break;
  412.         }
  413.  
  414.         if (all)
  415.             window++;
  416.     }
  417.  
  418.     wind_set(_last_top=top,WF_TOP);
  419. }
  420.  
  421. static int handle_messag(XEVENT *event,int no_messag,int flags)
  422. {
  423.     DRAG_DROP dd;
  424.     reg SCROLL *sc;
  425.     reg WIN *window;
  426.     reg int events = event->ev_mwich,state,old_h,old_v;
  427.     reg int *msg = event->ev_mmgpbuf;
  428.     reg long pos;
  429.  
  430.     if (_XAccComm(msg)==FALSE)
  431.     {
  432.         if (msg[0]==WM_M_BDROPPED)
  433.             msg[0] = WM_BOTTOMED;
  434.  
  435.         if (_dia_len>0 || _popup)
  436.             switch (msg[0])
  437.             {
  438.             case AC_CLOSE:
  439.             case AC_OPEN:
  440.             case AP_TERM:
  441.             case MN_SELECTED:
  442.             case WM_SHADED:
  443.             case WM_UNSHADED:
  444.             case WM_ICONIFY:
  445.             case WM_UNICONIFY:
  446.             case WM_CLOSED:
  447.             case WM_REDRAW:
  448.             case WM_MOVED:
  449.             case WM_FULLED:
  450.             case WM_SIZED:
  451.             case WM_ONTOP:
  452.             case WM_NEWTOP:
  453.             case WM_TOPPED:
  454.             case WM_UNTOPPED:
  455.             case WM_BOTTOMED:
  456.             case WM_HSLID:
  457.             case WM_VSLID:
  458.             case WM_ARROWED:
  459.                 _send_puf(msg[0],msg);
  460.                 return (events & (~MU_MESAG));
  461.             }
  462.  
  463.         switch (msg[0])
  464.         {
  465.         case AP_DRAGDROP:
  466.             _rec_ddmsg(msg);
  467.             events &= ~MU_MESAG;
  468.             break;
  469.         case VA_START:
  470.             dd.dd_type = AV_START;
  471.             dd.dd_win = NULL;
  472.             dd.dd_mx = dd.dd_my = -1;
  473.             dd.dd_kstate = event->ev_mmokstate;
  474.             dd.dd_args = *(char **) &msg[3];
  475.             goto _drag_msg;
  476.         case VA_DRAGACCWIND:
  477.             dd.dd_type = AV_DRAG;
  478.             dd.dd_win = get_window(msg[3]);
  479.             dd.dd_mx = msg[4];
  480.             dd.dd_my = msg[5];
  481.             dd.dd_kstate = event->ev_mmokstate;
  482.             dd.dd_args = *(char **) &msg[6];
  483.             _drag_msg:
  484.             dd.dd_originator = msg[1];
  485.             dd.dd_mem = dd.dd_name = NULL;
  486.             dd.dd_ext[0] = '\0';
  487.             dd.dd_size = 0l;
  488.             _send_msg(&dd,0,OBJC_DRAGGED,0,0);
  489.             events &= ~MU_MESAG;
  490.             break;
  491.         case WIN_TOPPED:
  492.             msg[0] = WM_TOPPED;
  493.             break;
  494.         case WIN_CLOSED:
  495.             msg[0] = WM_CLOSED;
  496.             break;
  497.         case MN_SELECTED:
  498.             if (_cycle>0 && msg[4]==_cycle)
  499.             {
  500.                 _cycle_close_window(TRUE,msg[3]);
  501.                 events &= ~MU_MESAG;
  502.             }
  503.             else if (_close>0 && msg[4]==_close)
  504.             {
  505.                 _cycle_close_window(FALSE,msg[3]);
  506.                 events &= ~MU_MESAG;
  507.             }
  508.             break;
  509.         case WIN_INFO:
  510.         case WIN_NAME:
  511.             if ((window=get_window(msg[3]))!=NULL)
  512.             {
  513.                 char *set = *(char **) &msg[4];
  514.                 wind_set(msg[3],(msg[0]==WIN_INFO) ? WF_INFO : WF_NAME,set);
  515.                 events &= ~MU_MESAG;
  516.             }
  517.             break;
  518.         case WIN_HSLSIZE:
  519.         case WIN_VSLSIZE:
  520.         case WIN_HSLIDE:
  521.         case WIN_VSLIDE:
  522.             if ((window=get_window(msg[3]))!=NULL)
  523.             {
  524.                 switch (msg[0])
  525.                 {
  526.                 case WIN_HSLSIZE:
  527.                     msg[0] = WF_HSLSIZE;
  528.                     break;
  529.                 case WIN_VSLSIZE:
  530.                     msg[0] = WF_VSLSIZE;
  531.                     break;
  532.                 case WIN_HSLIDE:
  533.                     msg[0] = WF_HSLIDE;
  534.                     break;
  535.                 default:
  536.                     msg[0] = WF_VSLIDE;
  537.                 }
  538.  
  539.                 wind_set(msg[3],msg[0],msg[4]);
  540.                 events &= ~MU_MESAG;
  541.             }
  542.             break;
  543.         case WM_SHADED:
  544.             if ((window=get_window(msg[3]))!=NULL)
  545.             {
  546.                 window->iconified |= SHADE;
  547.                 goto _win_changed;
  548.             }
  549.             break;
  550.         case WM_UNSHADED:
  551.             if ((window=get_window(msg[3]))!=NULL)
  552.             {
  553.                 window->iconified &= ~SHADE;
  554.                 goto _win_changed;
  555.             }
  556.             break;
  557.         case WM_ICONIFY:
  558.             if ((window=get_window(msg[3]))!=NULL)
  559.             {
  560.                 wind_set(msg[3],WF_ICONIFY,msg[4],msg[5],msg[6],msg[7]);
  561.                 if (window->icon_name)
  562.                     wind_set(msg[3],WF_NAME,window->icon_name);
  563.                 wind_xget(window->handle,WF_WORKXYWH,&window->icf_work.g_x,&window->icf_work.g_y,&window->icf_work.g_w,&window->icf_work.g_h);
  564.                 window->iconified |= ICONIFIED;
  565.                 goto _win_changed;
  566.             }
  567.             break;
  568.         case WM_UNICONIFY:
  569.             if ((window=get_window(msg[3]))!=NULL)
  570.             {
  571.                 window->iconified &= ~ICONIFIED;
  572.                 wind_set(msg[3],WF_UNICONIFY,window->curr.g_x,window->curr.g_y,window->curr.g_w,window->curr.g_h);
  573.                 wind_set(msg[3],WF_CURRXYWH,window->curr.g_x,window->curr.g_y,window->curr.g_w,window->curr.g_h);
  574.                 window_name(window,window->name,window->icon_name);
  575.                 goto _win_changed;
  576.             }
  577.             break;
  578.         case WM_CLOSED:
  579.             state = (event->ev_mmokstate & (K_RSHIFT|K_LSHIFT|K_ALT));
  580.             if (_icfs!=NULL && state && (window=get_window(msg[3]))!=NULL)
  581.             {
  582.                 if (state & K_ALT)
  583.                 {
  584.                     iconify(window,FALSE);
  585.                     _win_changed:
  586.                     *(WIN **) &msg[4] = window;
  587.                 }
  588.                 else
  589.                 {
  590.                     iconify(window,TRUE);
  591.                     *(WIN **) &msg[4] = NULL;
  592.                 }
  593.                 msg[0] = WIN_CHANGED;
  594.                 _window_fast_mouse(window,FALSE);
  595.             }
  596.             break;
  597.         case WM_REDRAW:
  598.             if ((window=get_window(msg[3]))!=NULL && (window->redraw!=NULL || win_iconified(window)))
  599.             {
  600.                 redraw_window(window,(GRECT *) &msg[4]);
  601.                 events &= ~MU_MESAG;
  602.             }
  603.             break;
  604.         case WM_MOVED:
  605.             if ((window=get_window(msg[3]))!=NULL && win_iconified(window))
  606.             {
  607.                 wind_set(window->handle,WF_CURRXYWH,msg[4],msg[5],msg[6],msg[7]);
  608.                 wind_xget(window->handle,WF_WORKXYWH,&window->icf_work.g_x,&window->icf_work.g_y,&window->icf_work.g_w,&window->icf_work.g_h);
  609.                 events &= ~MU_MESAG;
  610.             }
  611.             break;
  612.         case WM_UNTOPPED:
  613.             if ((window=get_window(msg[3]))!=NULL)
  614.                 window->inside = FAIL;
  615.             break;
  616.         case WM_ONTOP:
  617.         case WM_NEWTOP:
  618.             _last_top = msg[3];
  619.             _reset_mouse();
  620.             break;
  621.         case WM_TOPPED:
  622.             if (!_bevent && _back_win && (flags & (MU_BUTTON1|MU_BUTTON2)))
  623.             {
  624.                 if ((window=get_window(msg[3]))!=NULL && !win_iconified(window) && rc_inside(event->ev_mmox,event->ev_mmoy,&window->work))
  625.                 {
  626.                     events &= ~MU_MESAG;
  627.                     event->ev_mmobutton = 1;
  628.                     event->ev_mb1return = event->ev_mb2return = 1;
  629.  
  630.                     if (event->ev_mb1clicks>=256 || (event->ev_mb1state & 1))
  631.                         events |= MU_BUTTON1;
  632.  
  633.                     if (event->ev_mb2clicks>=256 || (event->ev_mb2state & 1))
  634.                         events |= MU_BUTTON2;
  635.  
  636.                     if (_mouse_but() & 1)
  637.                         appl_tplay(record,3,100);
  638.                 }
  639.             }
  640.             break;
  641.         case WM_HSLID:
  642.         case WM_VSLID:
  643.         case WM_ARROWED:
  644.             if ((window=get_window(msg[3]))!=NULL && ((sc=window->scroll)!=NULL))
  645.             {
  646.                 old_h = sc->hpos;
  647.                 old_v = sc->vpos;
  648.  
  649.                 switch (msg[0])
  650.                 {
  651.                 case WM_HSLID:
  652.                     pos = msg[4];
  653.                     pos *= max(sc->hsize - sc->hpage,0);
  654.                     pos /= 1000;
  655.                     sc->hpos = (int) pos;
  656.                     break;
  657.                 case WM_VSLID:
  658.                     pos = msg[4];
  659.                     pos *= max(sc->vsize - sc->vpage,0);
  660.                     pos /= 1000;
  661.                     sc->vpos = (int) pos;
  662.                     break;
  663.                 default:
  664.                     for (;;)
  665.                     {
  666.                         _arrow_window(sc,msg[4],(winx && msg[5]<0) ? -msg[5] : 1);
  667.                         if (winx && msg[7]<0)
  668.                         {
  669.                             msg[4] = msg[6];
  670.                             msg[5] = msg[7];
  671.                             msg[7] = 0;
  672.                         }
  673.                         else
  674.                             break;
  675.                     }
  676.                 }
  677.  
  678.                 scroll_window(window,WIN_SCROLL,NULL);
  679.                 msg[0] = WIN_SCROLLED;
  680.                 *(WIN **) &msg[4] = window;
  681.                 msg[6] = old_h;
  682.                 msg[7] = old_v;
  683.             }
  684.             break;
  685.         case AV_SENDKEY:
  686.             events &= ~MU_MESAG;
  687.             if (flags & MU_KEYBD)
  688.             {
  689.                 events |= MU_KEYBD;
  690.                 event->ev_mkreturn = msg[4];
  691.                 event->ev_mmokstate = msg[3];
  692.             }
  693.             break;
  694.         case ACC_KEY:
  695.             events &= ~MU_MESAG;
  696.             if (flags & MU_KEYBD)
  697.             {
  698.                 events |= MU_KEYBD;
  699.                 event->ev_mkreturn = msg[3];
  700.                 event->ev_mmokstate = msg[4];
  701.                 XAccSendAck(msg[1],1);
  702.             }
  703.             else
  704.                 XAccSendAck(msg[1],0);
  705.             break;
  706.         case ACC_META:
  707.             if (_xacc_msgs & X_MSG_META)
  708.                 break;
  709.         case ACC_IMG:
  710.             if (_xacc_msgs & X_MSG_IMG)
  711.                 break;
  712.             XAccSendAck(msg[1],0);
  713.             events &= ~MU_MESAG;
  714.             break;
  715.         }
  716.  
  717.         if (no_messag==0 && (events & MU_MESAG))
  718.         {
  719.             event->ev_mwich = events;
  720.             _messag_handler(FALSE,event,NULL,NULL);
  721.             return (event->ev_mwich);
  722.         }
  723.         else
  724.             return (events);
  725.     }
  726.     else
  727.         return (events & (~MU_MESAG));
  728. }
  729.  
  730. typedef struct
  731. {
  732.     unsigned int ev_mtlocount,ev_mthicount;
  733. } E_TIMER;
  734.  
  735. typedef struct
  736. {
  737.     int ev_mmflags,ev_mmx,ev_mmy,ev_mmwidth,ev_mmheight;
  738. } E_MOUSE;
  739.  
  740. typedef struct
  741. {
  742.     int ev_mbclicks,ev_mbmask,ev_mbstate;
  743. } E_BUTTON;
  744.  
  745. static E_BUTTON click = {258,3,0}, no_click = {1,3,0};
  746. static int next_msg;
  747.  
  748. MESSAG _messages[MAX_MSG];
  749. int _msg_cnt;
  750.  
  751. void _send_puf(int msg_id,int *msg)
  752. {
  753.     reg int *mbuf, act = next_msg, last = _msg_cnt;
  754.  
  755.     mbuf = (int *) &_messages[act];
  756.     while (act!=last)
  757.     {
  758.         if (*mbuf==msg_id && mbuf[3]==msg[3])
  759.         {
  760.             if (msg_id==WM_REDRAW)
  761.             {
  762.                 mbuf[6] = max(mbuf[4]+mbuf[6],msg[4]+msg[6]);
  763.                 mbuf[7] = max(mbuf[5]+mbuf[7],msg[5]+msg[7]);
  764.                 Min(&mbuf[4],msg[4]);
  765.                 Min(&mbuf[5],msg[5]);
  766.                 mbuf[6] -= mbuf[4];
  767.                 mbuf[7] -= mbuf[5];
  768.             }
  769.             else
  770.                 memcpy(&mbuf[4],&msg[4],8);
  771.             return;
  772.         }
  773.         else if (++act==MAX_MSG)
  774.             mbuf = (int *) &_messages[act=0];
  775.         else
  776.             mbuf += 8;
  777.     }
  778.  
  779.     memcpy(mbuf,msg,16);
  780.     *mbuf++ = msg_id;
  781.     *mbuf++ = ap_id;
  782.     *mbuf++ = 0;
  783.  
  784.     if (++_msg_cnt==MAX_MSG)
  785.         _msg_cnt = 0;
  786. }
  787.  
  788. static int Wait_for_Event(XEVENT *event)
  789. {
  790.     E_MOUSE mu_m1;
  791.     E_BUTTON mu_button1;
  792.     E_TIMER mu_timer1;
  793.  
  794.     reg long timer,l_timer;
  795.     reg int events = 0,flags = event->ev_mflags,t_flags = (flags & (MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4));
  796.     int in,button = 0,nx,ny,in1,in3,in4,mouse,d,next_timer;
  797.     long time;
  798.  
  799.     event->ev_mflags &= MU_MESAG|MU_BUTTON|MU_KEYBD|MU_M1|MU_M2|MU_TIMER;
  800.  
  801.     if (flags & (MU_M3|MU_M4))
  802.     {
  803.         mu_m1 = *(E_MOUSE *) &event->ev_mm1flags;
  804.  
  805.         _mouse_pos(&nx,&ny);
  806.         in1 = rc_inside(nx,ny,(GRECT *) &event->ev_mm1x);
  807.         in3 = rc_inside(nx,ny,(GRECT *) &event->ev_mm3x);
  808.         in4 = rc_inside(nx,ny,(GRECT *) &event->ev_mm4x);
  809.  
  810.         event->ev_mm1flags = event->ev_mm1width = event->ev_mm1height = 1;
  811.         event->ev_mm1x = nx;
  812.         event->ev_mm1y = ny;
  813.  
  814.         event->ev_mflags |= MU_M1;
  815.     }
  816.  
  817.     if (flags & MU_BUTTON2)
  818.     {
  819.         mu_button1 = *(E_BUTTON *) &event->ev_mb1clicks;
  820.  
  821.         if (event->ev_mflags & MU_BUTTON1)
  822.         {
  823.             if (event->ev_mb1clicks<256 && event->ev_mb1state==0)
  824.             {
  825.                 if (event->ev_mb2clicks<256 && event->ev_mb2state==0)
  826.                     *(E_BUTTON *) &event->ev_mb1clicks = no_click;
  827.                 else
  828.                 {
  829.                     *(E_BUTTON *) &event->ev_mb1clicks = click;
  830.                     button = -1;
  831.                 }
  832.             }
  833.             else
  834.             {
  835.                 if (event->ev_mb2clicks<256 && event->ev_mb2state==0)
  836.                     button = -1;
  837.                 *(E_BUTTON *) &event->ev_mb1clicks = click;
  838.             }
  839.         }
  840.         else
  841.         {
  842.             *(E_BUTTON *) &event->ev_mb1clicks = *(E_BUTTON *) &event->ev_mb2clicks;
  843.             event->ev_mflags |= MU_BUTTON1;
  844.             button = 1;
  845.         }
  846.     }
  847.  
  848.     if (t_flags || button<0)
  849.     {
  850.         mu_timer1 = *(E_TIMER *) &event->ev_mt1locount;
  851.         event->ev_mflags |= MU_TIMER;
  852.     }
  853.  
  854.     do
  855.     {
  856.         if (t_flags)
  857.         {
  858.             time = clock()*5;
  859.  
  860.             if (t_flags & MU_TIMER1)
  861.             {
  862.                 timer = (((long) event->ev_mt1hicount)<<16)|event->ev_mt1locount;
  863.                 if (event->ev_mt1last<=0)
  864.                     event->ev_mt1last = time;
  865.                 else
  866.                     timer += event->ev_mt1last - time;
  867.                 next_timer = MU_TIMER1;
  868.             }
  869.             else
  870.             {
  871.                 timer = (1l<<30);
  872.                 next_timer = 0;
  873.             }
  874.  
  875.             if (t_flags & MU_TIMER2)
  876.             {
  877.                 l_timer = event->ev_mt2count;
  878.                 if (event->ev_mt2last<=0)
  879.                     event->ev_mt2last = time;
  880.                 else
  881.                     l_timer += event->ev_mt2last - time;
  882.                 if (l_timer<timer)
  883.                 {
  884.                     timer = l_timer;
  885.                     next_timer = MU_TIMER2;
  886.                 }
  887.             }
  888.  
  889.             if (t_flags & MU_TIMER3)
  890.             {
  891.                 l_timer = event->ev_mt3count;
  892.                 if (event->ev_mt3last<=0)
  893.                     event->ev_mt3last = time;
  894.                 else
  895.                     l_timer += event->ev_mt3last - time;
  896.                 if (l_timer<timer)
  897.                 {
  898.                     timer = l_timer;
  899.                     next_timer = MU_TIMER3;
  900.                 }
  901.             }
  902.  
  903.             if (t_flags & MU_TIMER4)
  904.             {
  905.                 l_timer = event->ev_mt4count;
  906.                 if (event->ev_mt4last<=0)
  907.                     event->ev_mt4last = time;
  908.                 else
  909.                     l_timer += event->ev_mt4last - time;
  910.                 if (l_timer<timer)
  911.                 {
  912.                     timer = l_timer;
  913.                     next_timer = MU_TIMER4;
  914.                 }
  915.             }
  916.  
  917.             if (timer<=(long) _min_timer || button<0)
  918.             {
  919.                 event->ev_mthicount = 0;
  920.                 event->ev_mtlocount = _min_timer;
  921.                 events = MU_TIMER;
  922.             }
  923.             else
  924.             {
  925.                 event->ev_mtlocount = (int) timer;
  926.                 event->ev_mthicount = (int) (timer>>16);
  927.             }
  928.  
  929.             if (timer>0)
  930.                 time += timer;
  931.         }
  932.         else if (button<0)
  933.         {
  934.             event->ev_mthicount = 0;
  935.             event->ev_mtlocount = _min_timer;
  936.             events = MU_TIMER;
  937.         }
  938.  
  939.         if ((flags & MU_MESAG) && _msg_cnt!=next_msg && _dia_len==0 && _popup==0)
  940.         {
  941.             *(MESSAG *) &event->ev_mmgpbuf[0] = _messages[next_msg++];
  942.             if (next_msg==MAX_MSG)
  943.                 next_msg = 0;
  944.             events |= MU_MESAG;
  945.             graf_mkstate(&event->ev_mmox,&event->ev_mmoy,&event->ev_mmobutton,&event->ev_mmokstate);
  946.         }
  947.         else if (events & MU_TIMER)
  948.         {
  949.             events |= EvntMulti((EVENT *) event);
  950.             if (!(events & MU_BUTTON1))
  951.                 graf_mkstate(&d,&d,&event->ev_mmobutton,&event->ev_mmokstate);
  952.         }
  953.         else
  954.             events |= EvntMulti((EVENT *) event);
  955.  
  956.         if (!_bevent && _back_win)
  957.         {
  958.             event->ev_mmobutton = _mouse_but();
  959.             mouse = TRUE;
  960.  
  961.             if (events & MU_BUTTON1)
  962.             {
  963.                 in = event->ev_mmobutton & event->ev_mb1mask;
  964.  
  965.                 if (event->ev_mb1clicks<256)
  966.                 {
  967.                     if (in!=event->ev_mb1state)
  968.                         events &= ~MU_BUTTON1;
  969.                 }
  970.                 else if (in==0)
  971.                     events &= ~MU_BUTTON1;
  972.             }
  973.         }
  974.         else
  975.             mouse = FALSE;
  976.  
  977.         if (flags & MU_BUTTON2)
  978.         {
  979.             event->ev_mb2return = event->ev_mb1return;
  980.  
  981.             if (button>0)
  982.             {
  983.                 if (events & MU_BUTTON1)
  984.                 {
  985.                     events &= ~MU_BUTTON1;
  986.                     events |= MU_BUTTON2;
  987.                 }
  988.             }
  989.             else if (button<0 || (events & MU_BUTTON1))
  990.             {
  991.                 if (events & MU_BUTTON1)
  992.                     events &= ~MU_BUTTON1;
  993.                 else
  994.                 {
  995.                     if (mouse==FALSE)
  996.                         event->ev_mmobutton = _mouse_but();
  997.                     event->ev_mb2return = event->ev_mb1return = 1;
  998.                 }
  999.  
  1000.                 in = event->ev_mmobutton & event->ev_mb2mask;
  1001.                 if (event->ev_mb2clicks<256)
  1002.                 {
  1003.                     if (in==event->ev_mb2state)
  1004.                     {
  1005.                         events |= MU_BUTTON2;
  1006.                         if (in==0 && button<0)
  1007.                             event->ev_mb2return = 1;
  1008.                     }
  1009.                 }
  1010.                 else if (in)
  1011.                     events |= MU_BUTTON2;
  1012.  
  1013.                 in = event->ev_mmobutton & mu_button1.ev_mbmask;
  1014.                 if (mu_button1.ev_mbclicks<256)
  1015.                 {
  1016.                     if (in==mu_button1.ev_mbstate)
  1017.                     {
  1018.                         events |= MU_BUTTON1;
  1019.                         if (in==0 && button<0)
  1020.                             event->ev_mb1return = 1;
  1021.                     }
  1022.                 }
  1023.                 else if (in)
  1024.                     events |= MU_BUTTON1;
  1025.             }
  1026.         }
  1027.  
  1028.         if ((events & MU_M1) && (flags & (MU_M3|MU_M4)))
  1029.         {
  1030.             events &= ~MU_M1;        
  1031.  
  1032.             ny = event->ev_mmox;
  1033.             nx = event->ev_mmoy;
  1034.  
  1035.             if (flags & MU_M1)
  1036.             {
  1037.                 in = rc_inside(nx,ny,(GRECT *) &mu_m1.ev_mmx) - in1;
  1038.                 if ((in<0 && mu_m1.ev_mmflags) || (in>0 && mu_m1.ev_mmflags==0))
  1039.                     events |= MU_M1;
  1040.             }
  1041.  
  1042.             if (flags & MU_M3)
  1043.             {
  1044.                 in = rc_inside(nx,ny,(GRECT *) event->ev_mm3x) - in3;
  1045.                 if ((in<0 && event->ev_mm3flags) || (in>0 && event->ev_mm3flags==0))
  1046.                     events |= MU_M3;
  1047.             }
  1048.  
  1049.             if (flags & MU_M4)
  1050.             {
  1051.                 in = rc_inside(nx,ny,(GRECT *) event->ev_mm4x) - in4;
  1052.                 if ((in<0 && event->ev_mm4flags) || (in>0 && event->ev_mm4flags==0))
  1053.                     events |= MU_M4;
  1054.             }
  1055.         }
  1056.  
  1057.         if (events & MU_TIMER)
  1058.         {
  1059.             if (t_flags && (timer<=(long) _min_timer || button>=0))
  1060.             {
  1061.                 events &= ~MU_TIMER;
  1062.                 events |= next_timer;
  1063.  
  1064.                 switch (next_timer)
  1065.                 {
  1066.                 case MU_TIMER2:
  1067.                     event->ev_mt2last = time;
  1068.                     break;
  1069.                 case MU_TIMER3:
  1070.                     event->ev_mt3last = time;
  1071.                     break;
  1072.                 case MU_TIMER4:
  1073.                     event->ev_mt4last = time;
  1074.                     break;
  1075.                 default:
  1076.                     event->ev_mt1last = time;
  1077.                 }
  1078.             }
  1079.             else
  1080.                 events &= ~MU_TIMER;
  1081.         }
  1082.     } while (events==0);
  1083.  
  1084.     if (flags & (MU_M3|MU_M4))
  1085.         *(E_MOUSE *) &event->ev_mm1flags = mu_m1;
  1086.  
  1087.     if (t_flags || button<0)
  1088.         *(E_TIMER *) &event->ev_mt1locount = mu_timer1;
  1089.  
  1090.     if (flags & MU_BUTTON2)
  1091.         *(E_BUTTON *) &event->ev_mb1clicks = mu_button1;
  1092.  
  1093.     event->ev_mwich = events;
  1094.     event->ev_mflags = flags;
  1095.  
  1096.     return (events);
  1097. }
  1098.  
  1099. int Event_Multi(XEVENT *event)
  1100. {
  1101.     E_BUTTON mu_button1;
  1102.     reg WIN *window;
  1103.     XEVENT local_event;
  1104.     reg int events,no_messag,wait_events,key,flags;
  1105.     int mesag,available,old_flags,button;
  1106.  
  1107.     if (event==NULL)
  1108.     {
  1109.         event = &local_event;
  1110.         memset(event,0,sizeof(XEVENT));
  1111.         old_flags = no_messag = wait_events = 0;
  1112.     }
  1113.     else
  1114.     {
  1115.         old_flags = event->ev_mflags;
  1116.         no_messag = (old_flags & MU_NO_HANDLER);
  1117.         wait_events = (old_flags & (MU_MESAG|MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4));
  1118.     }
  1119.  
  1120.     if (_popup)
  1121.         available = MU_MESAG|MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4;
  1122.     else if (_no_button)
  1123.         available = MU_MESAG|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4;
  1124.     else
  1125.         available = MU_MESAG|MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4;
  1126.     available &= ~(wait_events & (MU_BUTTON1|MU_BUTTON2|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2|MU_TIMER3|MU_TIMER4));
  1127.  
  1128.     do
  1129.     {
  1130.         flags = wait_events;
  1131.         if (event_init!=NULL)
  1132.             flags |= (handler_events = event_init(event,available) & available);
  1133.         else if (event_handler!=NULL && !_popup)
  1134.             handler_events = available;
  1135.         else
  1136.             handler_events = 0;
  1137.  
  1138.         if (_icfs!=NULL && _opened>0 && _dia_len==0 && _popup==0)
  1139.         {
  1140.             if (!(flags & (MU_BUTTON1|MU_BUTTON2)) && (available & MU_BUTTON1))
  1141.             {
  1142.                 flags |= MU_BUTTON1;
  1143.  
  1144.                 mu_button1 = *(E_BUTTON *) &event->ev_mb1clicks;
  1145.                 *(E_BUTTON *) &event->ev_mb1clicks = click;
  1146.                 button = TRUE;
  1147.             }
  1148.             else
  1149.                 button = FALSE;
  1150.  
  1151.             if (!(flags & MU_KEYBD) && (available & MU_KEYBD))
  1152.                 flags |= MU_KEYBD;
  1153.         }
  1154.         else
  1155.             button = FAIL;
  1156.  
  1157.         event->ev_mflags = flags;
  1158.         events = Wait_for_Event(event);
  1159.         event->ev_mflags = old_flags;
  1160.  
  1161.         if (button>=FALSE)
  1162.         {
  1163.             if (button==TRUE)
  1164.                 *(E_BUTTON *) &event->ev_mb1clicks = mu_button1;
  1165.             if (event->ev_mmobutton & 1)
  1166.                 if ((window=window_find(event->ev_mmox,event->ev_mmoy))!=NULL && (window->iconified & ICFS) && rc_inside(event->ev_mmox,event->ev_mmoy,&window->icf_work))
  1167.                     if (!(events & MU_MESAG) || event->ev_mmgpbuf[0]!=WM_MOVED)
  1168.                     {
  1169.                         _icfs_iconify(window,FALSE,FALSE);
  1170.                         _send_msg(window,0,WIN_CHANGED,0,0);
  1171.                         events &= ~(MU_BUTTON1|MU_BUTTON2);
  1172.                         _no_click();
  1173.                     }
  1174.         }
  1175.  
  1176.         mesag = 0;
  1177.         if (events & MU_MESAG)
  1178.         {
  1179.             if (old_flags & MU_GET_MESSAG)
  1180.                 mesag = MU_MESAG;
  1181.             events = handle_messag(event,no_messag,flags);
  1182.         }
  1183.  
  1184.         if ((events & MU_KEYBD) && _opened>0 && _dia_len==0 && _popup==0 && (event->ev_mmokstate & K_CTRL) && (window=get_top_window())!=NULL)
  1185.         {
  1186.             button = event->ev_mkreturn>>8;
  1187.             if (button==0x66)
  1188.             {
  1189.                 int mbuf[8];
  1190.                 mbuf[3] = window->handle;
  1191.                 _send_puf(WM_FULLED,mbuf);
  1192.                 events &= ~MU_KEYBD;
  1193.             }
  1194.             else if (button==0x39 && _icfs!=NULL)
  1195.             {
  1196.                 if (event->ev_mmokstate & (K_LSHIFT|K_RSHIFT))
  1197.                 {
  1198.                     iconify(window,TRUE);
  1199.                     _send_msg(NULL,0,WIN_CHANGED,0,0);
  1200.                 }
  1201.                 else
  1202.                 {
  1203.                     _icfs_iconify(window,!(window->iconified & ICFS),window->handle);
  1204.                     _send_msg(window,0,WIN_CHANGED,0,0);
  1205.                 }
  1206.                 events &= ~MU_KEYBD;
  1207.             }
  1208.             else if ((key=scan_2_ascii(event->ev_mkreturn,event->ev_mmokstate))!='\0')
  1209.             {
  1210.                 key = UpperChar(key);
  1211.                 if (key==_cycle_hot || key==_close_hot)
  1212.                 {
  1213.                     _cycle_close_window(key==_cycle_hot,0);
  1214.                     events &= ~MU_KEYBD;
  1215.                 }
  1216.             }
  1217.         }
  1218.  
  1219.         if (no_messag==0)
  1220.         {
  1221.             if (handler_events & events)
  1222.                 events &= ~_call_event_handler(events,event,(wait_events & MU_KEYBD) ? FALSE : FAIL);
  1223.             events &= wait_events;
  1224.         }
  1225.  
  1226.         events |= mesag;
  1227.     } while (!events);
  1228.  
  1229.     return (event->ev_mwich = events);
  1230. }
  1231.  
  1232. void rc_sc_clear(GRECT *dest)
  1233. {
  1234.     rc_sc_copy(dest,dest->g_x,dest->g_y,0);
  1235. }
  1236.  
  1237. void rc_sc_invert(GRECT *dest)
  1238. {
  1239.     rc_sc_copy(dest,dest->g_x,dest->g_y,D_INVERT);
  1240. }
  1241.  
  1242. void rc_sc_copy(GRECT *source,int dx,int dy,int mode)
  1243. {
  1244.     reg int pxy[8];
  1245.  
  1246.     rc_grect_to_array(source,pxy);
  1247.  
  1248.     pxy[4] = dx;
  1249.     pxy[5] = dy;
  1250.     pxy[6] = dx+source->g_w-1;
  1251.     pxy[7] = dy+source->g_h-1;
  1252.  
  1253.     vro_cpyfm(x_handle,mode,pxy,screen,screen);
  1254. }
  1255.  
  1256. int rc_sc_scroll(GRECT *work,int dist_h,int dist_v,GRECT *work2)
  1257. {
  1258.     reg int dx,dy,abs_dist_h,abs_dist_v;
  1259.     int x,y,w,h;
  1260.  
  1261.     if (!rc_intersect(&desk,work))
  1262.         return (0);
  1263.     else if (dist_h==0 && dist_v==0)
  1264.         return (1);
  1265.  
  1266.     abs_dist_h = abs(dist_h);
  1267.     abs_dist_v = abs(dist_v);
  1268.  
  1269.     w = work->g_w;
  1270.     h = work->g_h;
  1271.  
  1272.     if (abs_dist_h<w && abs_dist_v<h)
  1273.     {
  1274.         dx = x = work->g_x;
  1275.         dy = y = work->g_y;
  1276.  
  1277.         if (dist_h>0)
  1278.             work->g_x += abs_dist_h;
  1279.         else
  1280.             dx += abs_dist_h;
  1281.  
  1282.         if (dist_v>0)
  1283.             work->g_y += abs_dist_v;
  1284.         else
  1285.             dy += abs_dist_v;
  1286.  
  1287.         work->g_w -= abs_dist_h;
  1288.         work->g_h -= abs_dist_v;
  1289.         rc_sc_copy(work,dx,dy,3);
  1290.  
  1291.         if (abs_dist_h && abs_dist_v)
  1292.         {
  1293.             work2->g_x = x;
  1294.             if (dist_h>0)
  1295.                 work2->g_x += work->g_w;
  1296.             work2->g_y = y;
  1297.             work2->g_w = abs_dist_h;
  1298.             work2->g_h = h - abs_dist_v;
  1299.  
  1300.             work->g_x = x;
  1301.             if (dist_v>0)
  1302.                 work->g_y = y + work->g_h;
  1303.             else
  1304.                 work2->g_y += abs_dist_v;
  1305.  
  1306.             work->g_w = w;
  1307.             work->g_h = abs_dist_v;
  1308.  
  1309.             return (2);
  1310.         }
  1311.         else if (abs_dist_h)
  1312.         {
  1313.             if (dist_h>0)
  1314.                 work->g_x = x + work->g_w;
  1315.             work->g_w = abs_dist_h;
  1316.         }
  1317.         else
  1318.         {
  1319.             if (dist_v>0)
  1320.                 work->g_y = y + work->g_h;
  1321.             work->g_h = abs_dist_v;
  1322.         }
  1323.     }
  1324.  
  1325.     return (1);
  1326. }
  1327.  
  1328. int rc_sc_save(GRECT *rect,RC_RECT *rc)
  1329. {
  1330.     reg int pxy[8],*ptr = &pxy[4];
  1331.     reg long mem,len;
  1332.  
  1333.     mfdb(&rc->mfdb,NULL,rect->g_w,rect->g_h,0,planes);
  1334.     len = mfdb_size(&rc->mfdb);
  1335.  
  1336.     if (rect->g_x>=0 && rect->g_y>=0 && (rect->g_x+rect->g_w)<=max_w && (rect->g_y+rect->g_h)<=max_h &&
  1337.         (mem=(long) malloc(len+16l))>0l)
  1338.     {
  1339.         rc->mem = (void *) mem;
  1340.         rc->area = *rect;
  1341.         rc->mfdb.fd_addr = (int *) ((mem+1) & (~1l));
  1342.  
  1343.         rc_grect_to_array(&rc->area,pxy);
  1344.         *ptr++ = 0;
  1345.         *ptr++ = 0;
  1346.         *ptr++ = rc->area.g_w - 1;
  1347.         *ptr++ = rc->area.g_h - 1;
  1348.         vro_cpyfm(x_handle,3,pxy,screen,&rc->mfdb);
  1349.  
  1350.         rc->valid = TRUE;
  1351.     }
  1352.     else
  1353.         rc->valid = FALSE;
  1354.  
  1355.     return (rc->valid);
  1356. }
  1357.  
  1358. int _rc_sc_savetree(OBJECT *tree,RC_RECT *rc)
  1359. {
  1360.     GRECT save;
  1361.     int valid;
  1362.  
  1363.     save.g_x = tree->ob_x - 3;
  1364.     save.g_y = tree->ob_y - 3;
  1365.     save.g_w = tree->ob_width + 6;
  1366.     save.g_h = tree->ob_height + 6;
  1367.  
  1368.     MouseOff();
  1369.     valid = rc_sc_save(&save,rc);
  1370.     MouseOn();
  1371.  
  1372.     return (valid);
  1373. }
  1374.  
  1375. int rc_sc_freshen(int sx,int sy,RC_RECT *rc)
  1376. {
  1377.     reg int pxy[8],*ptr = &pxy[4];
  1378.     reg GRECT *area = &rc->area;
  1379.  
  1380.     if (rc->valid && (sx+area->g_w)<=max_w && (sy+area->g_h)<=max_h)
  1381.     {
  1382.         area->g_x = sx;
  1383.         area->g_y = sy;
  1384.  
  1385.         rc_grect_to_array(area,pxy);
  1386.         *ptr++ = 0;
  1387.         *ptr++ = 0;
  1388.         *ptr++ = area->g_w - 1;
  1389.         *ptr++ = area->g_h - 1;
  1390.         vro_cpyfm(x_handle,3,pxy,screen,&rc->mfdb);
  1391.  
  1392.         return (TRUE);
  1393.     }
  1394.     else
  1395.         return (FALSE);
  1396. }
  1397.  
  1398. int rc_sc_restore(int x,int y,RC_RECT *rc,int mode)
  1399. {
  1400.     reg int pxy[8],*ptr = pxy;
  1401.  
  1402.     if (rc->valid)
  1403.     {
  1404.         if (mode!=FAIL)
  1405.         {
  1406.             *ptr++ = 0;
  1407.             *ptr++ = 0;
  1408.             *ptr++ = rc->area.g_w - 1;
  1409.             *ptr++ = rc->area.g_h - 1;
  1410.             *ptr++ = x;
  1411.             *ptr++ = y;
  1412.             *ptr++ = x + pxy[2];
  1413.             *ptr++ = y + pxy[3];
  1414.             vro_cpyfm(x_handle,3,pxy,&rc->mfdb,screen);
  1415.         }
  1416.  
  1417.         if (mode!=FALSE)
  1418.         {
  1419.             free(rc->mem);
  1420.             memset(rc,0,sizeof(RC_RECT));
  1421.         }
  1422.  
  1423.         return (TRUE);
  1424.     }
  1425.     else
  1426.         return (FALSE);
  1427. }
  1428.  
  1429. void save_clipping(int *area)
  1430. {
  1431.     reg long *clip=(long *) clipping_area;
  1432.  
  1433.     *((long *) area)++ = *clip++;
  1434.     *((long *) area)++ = *clip++;
  1435. }
  1436.  
  1437. void _clip_rect(GRECT *area)
  1438. {
  1439.     int pxy[4];
  1440.     rc_grect_to_array(area,pxy);
  1441.     restore_clipping(pxy);
  1442. }
  1443.  
  1444. void restore_clipping(int *area)
  1445. {
  1446.     reg long *clip=(long *) clipping_area;
  1447.  
  1448.     vs_clip(x_handle,1,area);
  1449.     *clip++ = *((long *) area)++;
  1450.     *clip++ = *((long *) area)++;
  1451. }
  1452.